﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

using System.IO;
using System.Drawing;
using System.Drawing.Imaging;

using System.Collections;
using Microsoft.SharePoint;
using Microsoft.SharePoint.UserCode;
using Microsoft.SharePoint.Workflow;

namespace EFSBWFActivities
{
    [ToolboxItemAttribute(true)]
    public class ShrinkImageSB
    {
        #region Logging
        public static void LogDebugInfo(SPUserCodeWorkflowContext context, string strMessage)
        {
#if DEBUG
            Log(context, strMessage);
#endif
        }

        public static void Log(SPUserCodeWorkflowContext context, string strMessage)
        {
            using (SPSite site = new SPSite(context.CurrentWebUrl))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPWorkflow.CreateHistoryEvent(web, context.WorkflowInstanceId, 0,
                        web.CurrentUser, TimeSpan.Zero, "ShrinkImageSB", strMessage, string.Empty);
                }
            }
        }
        #endregion

        //http://geekswithblogs.net/bullpit/archive/2009/04/29/compress-image-files-using-c.aspx

        /// <summary> 
        /// Saves an image as a jpeg image, with the given quality 
        /// </summary> 
        /// <param name="path">Path to which the image would be saved.</param> 
        // <param name="quality">An integer from 0 to 100, with 100 being the 
        /// highest quality</param> 
        public static void SaveJpeg(string path, Image img, int quality)
        {
            if (quality < 0 || quality > 100)
                throw new ArgumentOutOfRangeException("quality must be between 0 and 100.");

            // Encoder parameter for image quality
            EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
            // Jpeg image codec 
            ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");

            EncoderParameters encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = qualityParam;

            img.Save(path, jpegCodec, encoderParams);
        }

        /// <summary> 
        /// Returns the image codec with the given mime type 
        /// </summary> 
        private static ImageCodecInfo GetEncoderInfo(string mimeType)
        {
            // Get image codecs for all image formats 
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

            // Find the correct image codec 
            for (int i = 0; i < codecs.Length; i++)
                if (codecs[i].MimeType == mimeType)
                    return codecs[i];
            return null;
        }

        public static Hashtable Execute(SPUserCodeWorkflowContext context, Int32 Quality)
        {
            string strFilePath = string.Empty;

            Hashtable results = new Hashtable();
            results["Except"] = string.Empty;

            LogDebugInfo(context, string.Format("begin... Quality={0}", Quality));

            if (Quality <= 0 || Quality > 100)
            {
                Log(context, string.Format("Quality({0}) is invalid", Quality));
            }

            try
            {
                using (SPSite site = new SPSite(context.CurrentWebUrl))
                {
                    using (SPWeb objSPWeb = site.OpenWeb())
                    {
                        SPFile objSPFile = objSPWeb.GetFile(context.CurrentItemUrl);
                        byte[] imageData = objSPFile.OpenBinary(SPOpenBinaryOptions.Unprotected);
                        Image myImage = Image.FromStream(new MemoryStream(imageData));
                        strFilePath = objSPWeb.Url + objSPFile.Url;
                        LogDebugInfo(context, string.Format("strFilePath={0}", strFilePath));

                        //SaveJpeg(strFilePath, myImage, Quality);
                    }
                }

                results["Status"] = "Success";
            }
            catch (Exception ex)
            {
                Log(context, string.Format(@"ex.Message = {0}", ex.Message));
                Log(context, string.Format(@"ex.StackTrace = {0}", ex.StackTrace));
                results["Result"] = "Failure";
                results["Except"] = ex.ToString();
            }
            return results;
        }
    }
}
